package com.prevpn.service.impl;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.prevpn.api.GroupApi;
import com.prevpn.api.UserApi;
import com.prevpn.common.CommonResponse;
import com.prevpn.common.CommonUtil;
import com.prevpn.dto.AssignRoleByNameDTO;
import com.prevpn.dto.UserCreateDTO;
import com.prevpn.service.UserService;
import com.prevpn.vo.UserDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserApi userApi;

    @Autowired
    private GroupApi groupApi;
    /**
     * 新增用户
     */
    @Override
    public CommonResponse<Map<String, Object>> createUser(UserCreateDTO dto) {
        CommonResponse<Map<String, Object>> resp = new CommonResponse<>();

        // Step 1️⃣ 参数基础校验
        if (dto == null || StrUtil.isBlank(dto.getDirectoryDomain()) || StrUtil.isBlank(dto.getName()) || StrUtil.isBlank(dto.getEmail())) {
            resp.setCode("400");
            resp.setMsg("参数不完整：directoryDomain、name、email 必须填写");
            return resp;
        }
        if (dto.getGroup() == null || StrUtil.isBlank(dto.getGroup().getKey()) || StrUtil.isBlank(dto.getGroup().getData())) {
            resp.setCode("400");
            resp.setMsg("参数不完整：group.key 与 group.data 必须填写");
            return resp;
        }

        String directoryDomain = dto.getDirectoryDomain();
        String fullPath = dto.getGroup().getData();

        // Step 2️⃣ 检查组织架构是否存在，不存在则递归创建
        ensureGroupExists(directoryDomain, fullPath);

        // Step 3️⃣ 构造请求体 Map
        Map<String, Object> body = new HashMap<>();
        body.put("directoryDomain", directoryDomain);
        body.put("name", dto.getName());

        // 组织信息
        Map<String, Object> groupMap = new HashMap<>();
        groupMap.put("key", dto.getGroup().getKey());
        groupMap.put("data", fullPath);
        body.put("group", groupMap);

        // 外部 ID 与继承策略
        if (StrUtil.isNotBlank(dto.getExternalId())) body.put("externalId", dto.getExternalId());
        if (dto.getInheritGroup() != null) body.put("inheritGroup", dto.getInheritGroup());

        // Step 4️⃣ 密码处理（RSA 加密）
        if (StrUtil.isNotBlank(dto.getPassword())) {
            String encryptedPwd = dto.getPassword();
            if ("rsa".equalsIgnoreCase(dto.getPwdModel())) {
                encryptedPwd = CommonUtil.encrypt(dto.getPassword());
            }
            body.put("password", encryptedPwd);
            body.put("pwdModel", dto.getPwdModel());
        }

        // Step 5️⃣ 其他基本字段
        if (StrUtil.isNotBlank(dto.getDisplayName())) body.put("displayName", dto.getDisplayName());
        if (StrUtil.isNotBlank(dto.getDescription())) body.put("description", dto.getDescription());
        if (dto.getStatus() != null) body.put("status", dto.getStatus());
        if (StrUtil.isNotBlank(dto.getPhone())) body.put("phone", dto.getPhone());
        if (StrUtil.isNotBlank(dto.getEmail())) body.put("email", dto.getEmail());
        if (StrUtil.isNotBlank(dto.getExpiredTime())) body.put("expiredTime", dto.getExpiredTime());

        // Step 6️⃣ 数据来源 dataSource（可选）
        if (dto.getDataSource() != null) {
            Map<String, Object> ds = new HashMap<>();
            ds.put("displayName", dto.getDataSource().getDisplayName());
            ds.put("description", dto.getDataSource().getDescription());
            ds.put("status", dto.getDataSource().getStatus());
            ds.put("phone", dto.getDataSource().getPhone());
            ds.put("email", dto.getDataSource().getEmail());
            ds.put("expiredTime", dto.getDataSource().getExpiredTime());
            body.put("dataSource", ds);
        }

        // Step 7️⃣ 调用 UserApi.createUser(Map)
        CommonResponse<Map<String, Object>> apiResp = userApi.createUser(body);

        // Step 8️⃣ 返回结果封装
        if (!"OK".equalsIgnoreCase(apiResp.getCode())) {
            resp.setCode(apiResp.getCode());
            resp.setMsg("创建用户失败：" + apiResp.getMsg());
        } else {
            resp.setCode("OK");
            resp.setMsg("用户创建成功");
            resp.setData(apiResp.getData());
            resp.setTraceId(apiResp.getTraceId());
        }

        return resp;
    }

    // =====================================================
    // 辅助函数：自动递归创建父级组织架构
    // =====================================================
    private void ensureGroupExists(String directoryDomain, String fullPath) {
        if ("/".equals(fullPath) || StrUtil.isBlank(fullPath)) return;

        // 查询组织是否存在
        CommonResponse<Map<String, Object>> queryResp =
                groupApi.queryGroupByFullPath(directoryDomain, fullPath);

        if ("OK".equalsIgnoreCase(queryResp.getCode())) {
            return; // 已存在
        }

        // 上级路径
        String parentPath = getParentPath(fullPath);
        ensureGroupExists(directoryDomain, parentPath); // 递归创建上级

        // 当前组织名
        String[] parts = fullPath.split("/");
        String name = parts[parts.length - 1];

        // 创建当前组织
        CommonResponse<Map<String, Object>> createResp = groupApi.createGroup(
                directoryDomain,
                name,
                "fullPath",
                parentPath,
                "自动创建的组织",
                null
        );

        if ("OK".equalsIgnoreCase(createResp.getCode())) {
            System.out.println("自动创建组织架构：" + fullPath);
        } else {
            System.err.println("自动创建组织失败：" + fullPath + " → " + createResp.getMsg());
        }
    }

    // =====================================================
    // 辅助函数：获取父级路径（递归创建组织架构时使用）
    // =====================================================
    private String getParentPath(String fullPath) {
        int lastSlash = fullPath.lastIndexOf('/');
        if (lastSlash <= 0) return "/";
        return fullPath.substring(0, lastSlash);
    }

    /**
     * 通过邮箱查询用户详细信息
     */
    @Override
    public CommonResponse<UserDetailVO> queryUserByEmail(String directoryDomain, String email) {
        // Step 1️⃣: 调用查询用户列表接口（精确匹配邮箱）
        CommonResponse<Map<String, Object>> listResp =
                userApi.queryUserListByEmail(directoryDomain, email);

        if (!"OK".equalsIgnoreCase(listResp.getCode())) {
            CommonResponse<UserDetailVO> resp = new CommonResponse<>();
            resp.setCode(listResp.getCode());
            resp.setMsg("查询用户列表失败：" + listResp.getMsg());
            resp.setTraceId(listResp.getTraceId());
            return resp;
        }

        Map<String, Object> data = listResp.getData();
        if (data == null || !data.containsKey("data")) {
            CommonResponse<UserDetailVO> resp = new CommonResponse<>();
            resp.setCode("404");
            resp.setMsg("未找到邮箱对应的用户：" + email);
            return resp;
        }

        List<Map<String, Object>> users = (List<Map<String, Object>>) data.get("data");
        if (users.isEmpty()) {
            CommonResponse<UserDetailVO> resp = new CommonResponse<>();
            resp.setCode("404");
            resp.setMsg("未找到邮箱对应的用户：" + email);
            return resp;
        }

        // Step 2️⃣: 获取第一个匹配的用户 ID
        String userId = (String) users.get(0).get("id");

        // Step 3️⃣: 调用 /user/queryById 获取详细信息
        return userApi.queryUserById(directoryDomain, userId);
    }

    // 查询用户列表（支持分页、递归、模糊搜索）
    @Override
    public CommonResponse<Map<String, Object>> queryUserList(Map<String, Object> body) {
        CommonResponse<Map<String, Object>> resp = new CommonResponse<>();

        // 1️⃣ 参数校验
        if (body == null || !body.containsKey("directoryDomain")) {
            resp.setCode("400");
            resp.setMsg("参数不完整：directoryDomain 必须填写");
            return resp;
        }

        // 2️⃣ 分页参数：默认 pageSize=10, pageIndex=1
        int pageSize = parseIntOrDefault(body.get("pageSize"), 10);
        int pageIndex = parseIntOrDefault(body.get("pageIndex"), 1);

        // 3️⃣ recursive 参数：默认 1（递归）
        int recursive = parseIntOrDefault(body.get("recursive"), 1);

        body.put("pageSize", pageSize);
        body.put("pageIndex", pageIndex);
        body.put("recursive", recursive);

        // 4️⃣ 调用 aTrust OpenAPI
        return userApi.queryAllUsers(body);
    }

    private int parseIntOrDefault(Object value, int defaultVal) {
        if (value == null) return defaultVal;
        if (value instanceof Number) return ((Number) value).intValue();
        try {
            return Integer.parseInt(value.toString());
        } catch (Exception e) {
            return defaultVal;
        }
    }

    /**
     * 通过用户名查询用户详细信息
     */
    @Override
    public CommonResponse<UserDetailVO> queryUserByName(String directoryDomain, String name) {
        CommonResponse<Map<String, Object>> apiResp = userApi.queryUserByName(directoryDomain, name);

        CommonResponse<UserDetailVO> resp = new CommonResponse<>();
        resp.setCode(apiResp.getCode());
        resp.setMsg(apiResp.getMsg());
        resp.setTraceId(apiResp.getTraceId());

        if (!"OK".equalsIgnoreCase(apiResp.getCode())) {
            return resp;
        }

        // JSON 转换为 VO 对象
        UserDetailVO userDetail = JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getData()), UserDetailVO.class);
        resp.setData(userDetail);

        return resp;
    }

    @Override
    public CommonResponse<Map<String, Object>> assignRoleByName(AssignRoleByNameDTO dto) {
        CommonResponse<Map<String, Object>> resp = new CommonResponse<>();

        // ✅ 参数校验
        if (dto == null || StrUtil.isBlank(dto.getDirectoryDomain()) || StrUtil.isBlank(dto.getName()) ||
                dto.getRole() == null || StrUtil.isBlank(dto.getRole().getKey()) ||
                dto.getRole().getData() == null || dto.getRole().getData().isEmpty()) {
            resp.setCode("400");
            resp.setMsg("参数不完整：directoryDomain、name、role.key、role.data 必填");
            return resp;
        }

        // ✅ 构造 role 对象
        Map<String, Object> roleMap = new HashMap<>();
        roleMap.put("op", dto.getRole().getOp() != null ? dto.getRole().getOp() : "append");
        roleMap.put("key", dto.getRole().getKey());
        roleMap.put("data", dto.getRole().getData());

        // ✅ 调用 OpenAPI
        CommonResponse<Map<String, Object>> apiResp = userApi.assignRoleByName(
                dto.getDirectoryDomain(),
                dto.getName(),
                roleMap
        );

        // ✅ 返回结果
        resp.setCode(apiResp.getCode());
        resp.setMsg(apiResp.getMsg());
        resp.setTraceId(apiResp.getTraceId());
        resp.setData(apiResp.getData());
        return resp;
    }

    /**
     * 批量删除用户 - 基于名称
     */
    @Override
    public CommonResponse<Object> bulkDeleteUserByNameList(String directoryDomain, List<String> nameList) {
        CommonResponse<Object> resp = new CommonResponse<>();

        // === 参数校验 ===
        if (StrUtil.isBlank(directoryDomain)) {
            resp.setCode("400");
            resp.setMsg("参数不完整：directoryDomain 必须填写");
            return resp;
        }

        if (nameList == null || nameList.isEmpty()) {
            resp.setCode("400");
            resp.setMsg("参数不完整：nameList 必须为非空数组");
            return resp;
        }

        boolean hasEmpty = nameList.stream().anyMatch(StrUtil::isBlank);
        if (hasEmpty) {
            resp.setCode("400");
            resp.setMsg("参数错误：nameList 中包含空字符串");
            return resp;
        }

        // === 构造请求体 ===
        Map<String, Object> body = new HashMap<>();
        body.put("directoryDomain", directoryDomain);
        body.put("nameList", nameList);

        String json = JSONUtil.toJsonStr(body);

        // === 调用 OpenAPI ===
        CommonResponse<Object> apiResp = userApi.bulkDeleteUserByNameList(json);

        // === 返回统一结构 ===
        resp.setCode(apiResp.getCode());
        resp.setMsg(apiResp.getMsg());
        resp.setTraceId(apiResp.getTraceId());
        resp.setData(apiResp.getData());
        return resp;
    }

    /**
     * 编辑用户 - 基于名称
     */
    @Override
    public CommonResponse<Object> updateUserByName(Map<String, Object> body) {
        CommonResponse<Object> resp = new CommonResponse<>();

        // === 1️⃣ 参数校验 ===
        if (body == null) {
            resp.setCode("400");
            resp.setMsg("请求体不能为空");
            return resp;
        }

        Object directoryDomain = body.get("directoryDomain");
        Object name = body.get("name");

        if (directoryDomain == null || StrUtil.isBlankIfStr(directoryDomain)) {
            resp.setCode("400");
            resp.setMsg("参数不完整：directoryDomain 必须填写");
            return resp;
        }
        if (name == null || StrUtil.isBlankIfStr(name)) {
            resp.setCode("400");
            resp.setMsg("参数不完整：name 必须填写");
            return resp;
        }

        // === 2️⃣ 处理默认密码加密算法 ===
        Object password = body.get("password");
        if (password != null && StrUtil.isNotBlank(password.toString())) {
            // 默认加密方式为 rsa
            body.putIfAbsent("pwdModel", "rsa");
        }

        // === 3️⃣ 转 JSON 并调用 OpenAPI ===
        String json = JSONUtil.toJsonStr(body);
        CommonResponse<Object> apiResp = userApi.updateUserByName(json);

        // === 4️⃣ 返回统一结构 ===
        resp.setCode(apiResp.getCode());
        resp.setMsg(apiResp.getMsg());
        resp.setTraceId(apiResp.getTraceId());
        resp.setData(apiResp.getData());
        return resp;
    }

}
